package com.jandan.ui.server;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import com.jandan.ui.model.CnAndSentence;
import com.jandan.ui.model.LearnedWord;
import com.jandan.ui.model.Lesson;
import com.jandan.ui.model.SmallWordLibInfo;
import com.jandan.ui.model.Word;
import com.jandan.ui.model.WordComment;
import com.jandan.ui.model.WordLib;

public class DataMock {

	public static Map<Long, Lesson> lessonMap = new HashMap<Long, Lesson>();
	public static Map<Long, WordLib> wordLibMap = new HashMap<Long, WordLib>();
	public static Map<Long, Word> wordMap = new TreeMap<Long, Word>();
	public static Map<String, LearnedWord> learnedWordMap = new TreeMap<String, LearnedWord>();
	public static Map<Long,WordComment> wordCommentMap = new TreeMap<Long,WordComment>();
	public static Map<Long,Set<Long>> strangeWordRelation = new TreeMap<Long,Set<Long>>();

	public static long userID = 1;
//	private static boolean isInit = false;
//	
	static {
		init();
	}

	public static void init() {
		// word lib
		WordLib gre = new WordLib();

		gre.setWordLibID(nextWordLibID());
		// gre.setLearnedWordTableName("gre");
		gre.setWordLibName("GRE");
		gre.setDescription("data mock");
		gre.setCreatedDate(new Date());
		gre.setLibImagePath("images/libImages/no_reservations.jpg");
		gre.setFirstClass(10);
		gre.setSecondClass(20);
		gre.setThirdClass(30);
		gre.setForthClass(40);

		wordLibMap.put(gre.getWordLibID(), gre);

		WordLib tofel = new WordLib();
		tofel.setWordLibID(nextWordLibID());
		tofel.setWordLibName("TOFEL");
		tofel.setDescription("data mock");
		tofel.setCreatedDate(new Date());
		tofel.setLibImagePath("images/libImages/blood_diamond.jpg");
		tofel.setFirstClass(10);
		tofel.setSecondClass(20);
		tofel.setThirdClass(30);
		tofel.setForthClass(40);

		wordLibMap.put(tofel.getWordLibID(), tofel);

		String filePath = "c:/gre.txt";
		importWordLibData(filePath, gre.getWordLibID());

		filePath = "c:/toefl.txt";
		importWordLibData(filePath, tofel.getWordLibID());

//		isInit = true;
	}

	private static void importWordLibData(String filePath, long libID) {
		File file = new File(filePath);
		String fileName = file.getName();
		if (!file.isFile()
				|| !file.canRead()
				|| !fileName.substring(fileName.indexOf('.') + 1)
						.equalsIgnoreCase("txt")) {
			return;
		}
		
		BufferedReader in = null;

		try {
			in = new BufferedReader(new InputStreamReader(
					new FileInputStream(file), "UTF-8"));			
			String line = null;

			while ((line = in.readLine()) != null && line.length() > 0) {
				Word word = new Word();
				word.setWordID(nextWordID());
				String[] str = line.split("\\|");
				if (str == null || str.length < 4 || str[0] == null
						|| str[0].trim().length() <= 0) {
					continue;
				}

				word.setWordEn(str[0].trim());
				word.setPhonetics(str[1].trim());

				ArrayList<CnAndSentence> cnAndSentenceList = new ArrayList<CnAndSentence>();

				if (str[2] != null && str[2].trim().length() > 0) {
					String[] cc = str[2].trim().split("\\t");
					String[] ss = null;
					if (str[3] != null && str[3].trim().length() > 0) {
						ss = str[3].trim().split("\\t");
					}
					for (int j = 0; j < cc.length; j++) {
						CnAndSentence cs = new CnAndSentence();
						cs.setCsID(j);
						cs.setCn(cc[j]);
						if (ss != null && ss.length > j) {
							cs.setSentence(ss[j]);
						}
						cs.setWordID(word.getWordID());
						cnAndSentenceList.add(cs);
					}
				}

				word.setCnAndSentenceList(cnAndSentenceList);
				if (str.length > 4)
					word.setDescription(str[4].trim());

				word.setWordLibID(libID);
				wordMap.put(word.getWordID(), word);
			}
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		finally{
			if(in != null){
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public static List<WordLib> getWordLibList() {
		// TODO Auto-generated method stub
		return new ArrayList(wordLibMap.values());
	}

	public static WordLib getWordLibByID(long id) {
		// TODO Auto-generated method stub
		return wordLibMap.get(id);
	}

	public static List<Word> getWordList(long lessonID, int libNumber) {
		// TODO Auto-generated method stub
		Lesson lesson = lessonMap.get(lessonID);
		if (lesson != null) {
			long wordLibID = lesson.getWordLibID();
			int smallLibWordCount = lesson.getWordsCountOfPerSmallLib();
			WordLib wordLib = getWordLibByID(wordLibID);
			if (wordLib != null) {
				List<Word> wordList = getAllWordList(wordLibID);

				int wordCount = wordList.size();
				int n = (int) (wordCount / smallLibWordCount);
				if (libNumber <= n) {
					int fromIndex = libNumber * smallLibWordCount;
					int toIndex = (libNumber + 1) * smallLibWordCount;

					if (toIndex > wordCount)
						toIndex = wordCount;
					List<Word> list = new ArrayList<Word>();
					for (int i = fromIndex; i < toIndex; i++) {
						list.add(wordList.get(i));
					}
					return list;
				}
			}
		}
		return null;
	}

	public static Word getWordByWordID(long wordID) {
		// TODO Auto-generated method stub
		return wordMap.get(wordID);
	}

	public static void addLesson(Lesson lesson) {
		// TODO Auto-generated method stub
		// lesson.setSmallWordLibList(getSmallWordLibList(lesson.getWordLibID()));
		lesson.setLessonID(nextLessonID());
		lesson.setSmallWordLibList(getSmallWordLibList(lesson));
		lessonMap.put(lesson.getLessonID(), lesson);
	}

	public static Lesson getLesson(long lessonID) {
		// TODO Auto-generated method stub
		Lesson lesson = lessonMap.get(lessonID);
		lesson.setSmallWordLibList(getSmallWordLibList(lesson));
		return lesson;
	}

	public static List<Lesson> getLessonList(long userID) {
		// TODO Auto-generated method stub
		List<Lesson> list = new ArrayList<Lesson>();
		Iterator<Lesson> it = lessonMap.values().iterator();
		
		while(it.hasNext()){
			Lesson lesson = it.next();
			if(lesson.getUserID() == userID){
				lesson.setSmallWordLibList(getSmallWordLibList(lesson));
				list.add(lesson);
			}
		}
		return list;
	}

	private static List<SmallWordLibInfo> getSmallWordLibList(Lesson lesson) {
		// TODO Auto-generated method stub
		long wordLibID = lesson.getWordLibID();
		int smallLibWordCount = lesson.getWordsCountOfPerSmallLib();

		List<SmallWordLibInfo> smallWordLibList = new ArrayList<SmallWordLibInfo>();
		WordLib wordLib = getWordLibByID(wordLibID);

		if (wordLib != null) {
			List<Word> wordList = getAllWordList(wordLibID);
			int wordCount = wordList.size();
			int n = (int) (wordCount / smallLibWordCount);
			for (int i = 0; i <= n; i++) {
				int startNumber = i * smallLibWordCount;
				int endNumber = (i + 1) * smallLibWordCount - 1;
				if (i == n) {
					endNumber = wordCount - 1;
				}
				SmallWordLibInfo smallWordLib = new SmallWordLibInfo();
				smallWordLib
						.setStartWord(wordList.get(startNumber).getWordEn());
				smallWordLib.setEndWord(wordList.get(endNumber).getWordEn());
				smallWordLib.setTotalWordCount(endNumber - startNumber + 1);
				smallWordLib.setSmallWordNumber(i);
				smallWordLib.setLearnedWordCount(0);

				smallWordLibList.add(smallWordLib);
			}
		}
		return smallWordLibList;
	}

	public static void deleteLesson(long lessonID) {
		// TODO Auto-generated method stub
		lessonMap.remove(lessonID);
	}

	public static List<Word> getAllWordList(long wordLibID) {
		List<Word> wordList = new ArrayList<Word>();
		Iterator<Word> it = wordMap.values().iterator();
		while (it.hasNext()) {
			Word w = it.next();
			if (w.getWordLibID() == wordLibID) {
				wordList.add(w);
			}
		}
		return wordList;
	}

	public static List<Word> getWordListByWordLibID(long wordLibID, int start,
			int limit) {
		// TODO Auto-generated method stub
		List<Word> wordList = getAllWordList(wordLibID);
		int size = wordList.size();
		if (size <= start) {
			return new ArrayList<Word>();
		}
		int end = (start + limit) > size ? size : start + limit;
		return wordList.subList(start, end);
	}

	public static int getWordCountByWordLibID(long wordLibID) {
		return getAllWordList(wordLibID).size();
	}

	public static int getWordCountByWordLibID(long wordLibID, String startWord) {
		// TODO Auto-generated method stub
		List<Word> wordList = getAllWordList(wordLibID);
		int i = 0;
		Iterator<Word> it = wordList.iterator();
		if (startWord == null)
			return wordList.size();
		while (it.hasNext()) {
			Word w = it.next();
			String wordEn = w.getWordEn();
			if (wordEn != null && wordEn.startsWith(startWord)) {
				i++;
			}
		}
		return i;
	}

	public static List<Word> getWordList(long wordLibID, String startWord,
			int start, int limit) {
		// TODO Auto-generated method stub
		List<Word> wordList = getAllWordList(wordLibID);
		List<Word> list = new ArrayList<Word>();
		Iterator<Word> it = wordList.iterator();
		if (startWord == null)
			return list;
		while (it.hasNext()) {
			Word w = it.next();
			String wordEn = w.getWordEn();
			if (wordEn != null && wordEn.startsWith(startWord)) {
				list.add(w);
			}
		}
		int size = list.size();
		if (size <= start) {
			return new ArrayList<Word>();
		}
		int end = (start + limit) > size ? size : start + limit;
		return list.subList(start, end);
	}

	public static void addStrangeWord(Word word,int flag) {
		// TODO Auto-generated method stub
		//新建一个word，放到wordMap里面，然后再在
		if(flag == 1){		//将已有单词添加到生词本中
			Word sword = new Word();
			
			sword.setWordID(nextWordID());
			sword.setWordEn(word.getWordEn());
			sword.setDescription(word.getDescription());
			sword.setPhonetics(word.getPhonetics());
//			sword.setAynonymList(word.getAynonymList());
//			sword.setExtendedWordList(word.getExtendedWordList());
//			sword.setSimilarWordList(word.getSimilarWordList());
//			sword.setSynonymList(word.getSynonymList());
//			
			List<CnAndSentence> list = word.getCnAndSentenceList();
			int i = 0;
			for(Iterator<CnAndSentence> it = list.iterator();it.hasNext();i++){
				CnAndSentence cc = it.next();
				if(cc != null){
					cc.setCsID(i);
					cc.setWordID(sword.getWordID());
				}
			}
			
			sword.setCnAndSentenceList(word.getCnAndSentenceList());
			
			wordMap.put(sword.getWordID(), sword);
			Set<Long> swordIDs = strangeWordRelation.get(userID);
			if(swordIDs == null){
				swordIDs = new HashSet<Long>();
				strangeWordRelation.put(userID, swordIDs);
			}
			swordIDs.add(sword.getWordID());
		}
		else if(flag == 2){  //更新生词
			wordMap.put(word.getWordID(), word);
		}
	}

	public static List<Word> getWordListOfStrangeWord(long uid,int start, int limit) {
		// TODO Auto-generated method stub
		List<Word> wordList = getAllWordListOfStrangeWord(uid);
		int size = wordList.size();
		if (size <= start) {
			return new ArrayList<Word>();
		}
		int end = (start + limit) > size ? size : start + limit;
		return wordList.subList(start, end);
	}

	private static List<Word> getAllWordListOfStrangeWord(long uid) {
		// TODO Auto-generated method stub
//		return new ArrayList(notebookMap.values());
		Set<Long> set = strangeWordRelation.get(uid);
		List<Word> wordList = new ArrayList<Word>();
		
		if(set != null){
			for(Iterator<Long> it = set.iterator();it.hasNext();){
				long wid = it.next();
				Word w = wordMap.get(wid);
				if(w != null)
					wordList.add(w);
			}
		}
		
		return wordList;
	}

	public static int getWordCountOfStrangeWord(long uid) {
		// TODO Auto-generated method stub
		Set<Long> set = strangeWordRelation.get(uid);
		if(set == null)
			return 0;
		return set.size();
	}

	public static void writeback(List<LearnedWord> words) {
		// TODO Auto-generated method stub
		Iterator<LearnedWord> it = words.iterator();
		while (it.hasNext()) {
			LearnedWord w = it.next();
			learnedWordMap.put(w.getLearnedWordID(), w);
		}
	}

	public static List<LearnedWord> getLearnedWordList(long lessonID) {
		// TODO Auto-generated method stub
		Iterator<LearnedWord> it = learnedWordMap.values().iterator();
		List<LearnedWord> list = new ArrayList<LearnedWord>();
		while (it.hasNext()) {
			LearnedWord lw = it.next();
			if (lw.getLessonID() == lessonID){
				if(lw.getWord() == null){
					lw.setWord(getWordByWordID(lw.getWordID()));
				}
				list.add(lw);
			}
		}
		return list;
	}

	public static List<LearnedWord> getLearnedWordByLessonIDAndLibNumber(
			long lessonID, int libNumber, int start, int limit) {
		// TODO Auto-generated method stub
		return getLearnedWordList(lessonID);
	}

	public static int getLearnedWordCountByLessonIDAndLibNumber(long lessonID, int libNumber) {
		// TODO Auto-generated method stub
		return getLearnedWordList(lessonID).size();
	}

	private static long nextWordLibID() {
		return wordLibMap.size();
	}

	private static long nextWordID() {
		return wordMap.size();
	}

	private static long nextLessonID() {
		return lessonMap.size();
	}

	public static LearnedWord getLearnedWordByLearnedWordID(String learnedWordID) {
		// TODO Auto-generated method stub
		LearnedWord lw = learnedWordMap.get(learnedWordID);
		if(lw != null){
			if(lw.getWord() == null){
				lw.setWord(getWordByWordID(lw.getWordID()));
			}
		}
		return lw;
	}
	
//	private static long nextLearnedWordID() {
//		return learnedWordMap.size();
//	}

	public static List<WordComment> getWordCommentListByWordID(long wordID) {
		// TODO Auto-generated method stub
		List<WordComment> wordCommentList = new ArrayList<WordComment>();
		Iterator<WordComment> it = wordCommentMap.values().iterator();
		while(it.hasNext()){
			WordComment wc = it.next();
			
			if(wc != null && wc.getWordID() == wordID){
				wordCommentList.add(wc);
			}
		}
		
		return wordCommentList;
	}
	
	public static WordComment addWordComment(WordComment wordComment){
		wordComment.setWordCommentID(nextWordCommentID());
		wordCommentMap.put(wordComment.getWordCommentID(),wordComment);
		return wordComment;
	}
	
	private static long nextWordCommentID(){
		return wordCommentMap.size();
	}

	public static int getWordCommentCountByWordID(long wordID) {
		// TODO Auto-generated method stub
		return getWordCommentListByWordID(wordID).size();
	}

	public static void addStrangeWord(Word word, long userID2) {
		// TODO Auto-generated method stub
		
	}
}
